package com.boarsoft.boar.file.service;

import com.boarsoft.bean.ReplyInfo;
import com.boarsoft.boar.BaseConfig;
import com.boarsoft.boar.app.AppFileBiz;
import com.boarsoft.boar.app.AppInstBiz;
import com.boarsoft.boar.entity.AppInst;
import com.boarsoft.boar.entity.FileInfo;
import com.boarsoft.boar.entity.FileVersion;
import com.boarsoft.boar.file.FileBiz;
import com.boarsoft.boar.file.FileVersionBiz;
import com.boarsoft.boar.file.FileExtService;
import com.boarsoft.boar.service.FileService;
import com.boarsoft.common.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.util.List;

/********************************************
 * @系统名称： 四川农信分布式核心
 * @版本号： V1.0
 * @开发人员： 刘超
 * @创建日期： 2023/3/27 10:23
 * ------------------------------------------
 * @程序名称： OssFileServiceImpl
 * @业务模块： SC6000D 分布式核心-技术组
 * @程序类型：
 * @程序功能：
 * ------------------------------------------
 * @修改说明： 修改人：   修改日期：   修改原因：
 ********************************************/
public class ExtentionFileServiceImpl implements FileService {
    private static Logger log = LoggerFactory.getLogger(ExtentionFileServiceImpl.class);

    private FileExtService fileExtService;
    @Autowired
    private AppInstBiz appInstBiz;
    @Autowired
    private AppFileBiz appFileBiz;
    @Autowired
    private FileBiz fileBiz;
    @Autowired
    private FileVersionBiz fileVersionBiz;

    public void setFileExtService(FileExtService fileExtService) {
        this.fileExtService = fileExtService;
    }

    /**
     * @param by     修改人或节点地址
     * @param fileId
     * @param env
     * @param group  分组
     * @param bytes
     * @return
     */
    @Override
    public ReplyInfo<Object> commit(String by, String fileId, String env, String group, byte[] bytes) {
        FileVersion ov = fileVersionBiz.find(fileId, env, group);
        FileVersion nv = FileVersion.clone(ov);
        fileVersionBiz.save(nv);
        String fp = this.getFilePath(nv);
        log.warn("Writing file {} for file version {}", fp, nv.getId());
        boolean b = fileExtService.saveFile(fp, bytes);
        if (!b) {
            return new ReplyInfo<Object>("Save File Error");
        }
        ov.setStatus(FileVersion.STATUS_INACTIVE);
        fileVersionBiz.save(ov);
        nv.setStatus(FileVersion.STATUS_ACTIVE);
        fileVersionBiz.save(nv);
        return new ReplyInfo<Object>(true, nv);
    }

    /**
     * @param ip   发送配置文件请求的节点地址
     * @param port
     * @param code 请求的配置文件编号
     * @return 当前版本文件的路径
     */
    @Override
    public String find(String ip, int port, String code) {
        AppInst ai = appInstBiz.find(ip, port);
        String appId = ai.getAppId();
        FileInfo fi = appFileBiz.find(appId, code);
        FileVersion v = fileVersionBiz.find(fi.getId(), ai.getEnv(), ai.getGroup());
        return this.getFilePath(v);
    }

    /**
     * @param ip   发送配置文件请求的节点地址
     * @param port
     * @param code 请求的配置文件编号
     * @return
     * @throws IOException
     */
    @Override
    public byte[] load(String ip, int port, String code) throws IOException {
        String fp = this.find(ip, port, code);
        if (Util.strIsEmpty(fp)) {
            log.error("Can not find file {} for app inst {}:{}", code, ip, port);
            throw new IllegalStateException(String.format(//
                    "Can not find %s for app inst %s:%d", code, ip, port));
        }
        return fileExtService.getContent(fp);
    }

    /**
     * 上传配置文件到服务器，生成的版本
     *
     * @param ip
     * @param port
     * @param code
     * @param bytes
     * @return
     * @throws IOException
     */
    @Override
    public ReplyInfo<Object> commit(String ip, int port, String code, byte[] bytes) throws IOException {
        AppInst ai = appInstBiz.find(ip, port);
        FileInfo fi = appFileBiz.find(ai.getAppId(), code);
        String fp = this.find(ip, port, code);
        // 查找当前激活的版本
        FileVersion a = fileVersionBiz.find(fi.getId(), ai.getEnv(), ai.getGroup());
        // 复制当前版本（新增版本）
        FileVersion v = FileVersion.clone(a);
        fileVersionBiz.save(v);
        // 写入文件
        log.warn("Writing file {} for file version {}", fp, v.getId());
        boolean b = fileExtService.saveFile(fp, bytes);
        if (!b) {
            return new ReplyInfo<Object>("Save File Error");
        }
        // 修改当前版本状态为未激活
        a.setStatus(FileVersion.STATUS_INACTIVE);
        fileVersionBiz.save(a);
        // 激活新版本
        v.setStatus(FileVersion.STATUS_ACTIVE);
        fileVersionBiz.save(v);
        return new ReplyInfo<Object>(true, v);
    }

    /**
     * @param o
     * @return
     */
    @Override
    public String getFilePath(FileVersion o) {
        // 读取本地存储
        StringBuilder sb = new StringBuilder(BaseConfig.PATH_PRIVATE);
        sb.append("/").append(o.getEnv());
        if (Util.strIsEmpty(o.getPath())) {
            return sb.append("/").append(o.getFileId())//
                    .append("/").append(o.getId()).toString();
        }
        FileInfo fi = fileBiz.get(o.getFileId());
        return sb.append(o.getPath()).append(fi.getDeployPath()).toString();
    }

    /**
     * @param fileId
     * @param env
     * @param group
     * @return
     * @throws IOException
     */
    @Override
    public byte[] load(String fileId, String env, String group) throws IOException {
        FileVersion fv = fileVersionBiz.find(fileId, env, group);
        return this.load(fv);
    }

    /**
     * @param o
     * @return
     */
    @Override
    public byte[] load(FileVersion o) {
        if (o == null) {
            return null;
        }
        String fp = this.getFilePath(o);
        return fileExtService.getContent(fp);
    }

    @Override
    public void delete(String fileId, String env, String group) {
        List<FileVersion> lt = fileVersionBiz.list(fileId, env);
        for (FileVersion o : lt) {
            String fp = this.getFilePath(o);
            fileExtService.deleteFile(fp);
        }
    }
}
